package com.social.config;

import cn.hutool.core.bean.BeanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.Map;

//@Component
//public class RabbitmqConfirmCallback implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
//    private Logger logger = LoggerFactory.getLogger(RabbitmqConfirmCallback.class);
//
//    /**
//     * 监听消息是否到达Exchange
//     *
//     * @param correlationData 包含消息的唯一标识的对象
//     * @param ack             true 标识 ack，false 标识 nack
//     * @param cause           nack 投递失败的原因
//     */
//    @Override
//    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
//        if (ack) {
//            logger.info("消息投递成功~消息Id：{}", correlationData.getId());
//        } else {
//            logger.error("消息投递失败，Id：{}，错误提示：{}", correlationData.getId(), cause);
//        }
//    }
//
//    @Override
//    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
//        logger.info("消息没有路由到队列，获得返回的消息");
//        Map map = byteToObject(message.getBody(), Map.class);
//        logger.info("message body: {}", map == null ? "" : map.toString());
//        logger.info("replyCode: {}", replyCode);
//        logger.info("replyText: {}", replyText);
//        logger.info("exchange: {}", exchange);
//        logger.info("routingKey: {}", exchange);
//        logger.info("------------> end <------------");
//    }
//
//    @SuppressWarnings("unchecked")
//    private <T> T byteToObject(byte[] bytes, Class<T> clazz) {
//        T t;
//        try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
//             ObjectInputStream ois = new ObjectInputStream(bis)) {
//            t = (T) ois.readObject();
//        } catch (Exception e) {
//            e.printStackTrace();
//            return null;
//        }
//        return t;
//    }
//}
@Configuration
public class RabbitmqConfirmCallback{
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    //可靠性
    @Bean
    public void setConfirm(){
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
               // System.out.println("confirm");
                if (ack){
                    System.out.println("接收成功");
                }else {
                    System.out.println("接收失败："+cause);
                    String id = correlationData.getId();
                    String json = stringRedisTemplate.opsForValue().get(id);

                    if(json != null) {
                        Map map = BeanUtil.toBean(json, Map.class);
                        rabbitTemplate.convertAndSend(map.get("exchange").toString(), map.get("routing").toString(), map, correlationData);
                    }
                }
            }
        });
    }

    //回调
    @Bean
    public void setReturn(){
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                System.out.println("return....");
            }
        });
    }
}